/*
 * PMemoryPool.h
 *
 *  Created on: Sep 6, 2013
 *      Author: yuliang
 */

#ifndef PMEMORYPOOL_H_
#define PMEMORYPOOL_H_

#ifdef __UNITTEST
#include <stdio.h>
#endif

#include <stdint.h>

/*内存块个数*/
#define PMEMORYPOOL_MODEL 5 // !-勿修改-!, 如需要修改,需修改MemorySize的定义和CMemoryPool构造函数

/*
 * @brief       内存池类
 * @auther      lyl
 */
class CPMemoryPool {
private:
	/*内存块数组下标*/
	enum MemorySize {
		S_1 = 0,
		S_2,
		S_3,
		S_4,
		S_5,
	};
	/*内存地址*/
	typedef struct _memory {
		char *m_mem; // 大小为m_onesize
		_memory* nextidle; // 下一个内存地址
	}Memory;
public:
	CPMemoryPool();
	virtual ~CPMemoryPool();

	/*
	 * @brief       初始化
	 * @auther      lyl
	 * @param [in]  maxsize  : 内存最大值
	 * @param [in]  poolsize : 一个内存块的初始内存个数
	 * @return      bool   : false表示初始化失败,true表示初始化成功
	 */
	bool Init(uint32_t maxsize, uint32_t poolsize);

	/*
	 * @brief       判断所有内存都为闲置状态
	 * @auther      lyl
	 * @return      bool   : false表示有内存被占用,true表示所有内存都为闲置状态
	 */
	bool AllMemoryIdle() const;

	/*
	 * @brief       取出一块内存
	 * @auther      lyl
	 * @param [in]  len    : 数据块大小
	 * @return      char*  : NULL表示获取失败,其他表示内存地址
	 * @note        len<=maxsize,否则获取失败
	 */
	char *PopMem(uint32_t len);

	/*
	 * @brief       取出一块内存,并赋值
	 * @auther      lyl
	 * @param [in]  buf    : 数据块
	 * @param [in]  len    : 数据块大小
	 * @return      char*  : NULL表示获取失败,其他表示内存地址
	 */
	const char * PopMem(const char *buf, uint32_t len);

	/*
	 * @brief       放回内存吃
	 * @auther      lyl
	 * @param [in]  buf    : 数据块
	 * @param [in]  len    : 数据块大小
	 * @return      void
	 */
	void PushMem(char *buf, uint32_t len);
private:
	bool createOneMem(MemorySize i);
	Memory * createOneObj();
	void pushPool(Memory *, MemorySize i);
	MemorySize memSize(uint32_t len);
private:
	bool m_init;
	MemorySize m_index[PMEMORYPOOL_MODEL]; // 数组下标
	uint32_t m_onesize[PMEMORYPOOL_MODEL]; // 一个内存块大小
	uint32_t m_poolsize[PMEMORYPOOL_MODEL]; // 一个内存池大小
	Memory * m_curidlemem[PMEMORYPOOL_MODEL]; // 一个内存池中当前空闲内存
};

#endif /* PMEMORYPOOL_H_ */
